package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.commons.constants.CommonConstants;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.CourseAuditDto;
import com.xuecheng.commons.model.dto.CourseBaseDto;
import com.xuecheng.commons.model.dto.CourseDto;
import com.xuecheng.commons.model.dto.PageRequest;
import com.xuecheng.commons.model.vo.PageResponseResult;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.config.MinioProperties;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.mappers.CourseBaseMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.content.service.CoursePubService;
import com.xuecheng.content.service.TeachplanService;
import com.xuecheng.web.exception.BusinessException;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-07-16
 */
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {
        @Autowired
        private MinioClient minioClient;
        @Autowired
        private MinioProperties minioProperties;
        @Autowired
        private TeachplanService teachplanService;

        @Override
        public ResponseResult courseList(PageRequest pageRequest, CourseDto courseDto) {
                //创建分页对象
                Page<CourseBase> page = new Page<>(pageRequest.getPageNo(), pageRequest.getPageSize());
                // 创建查询条件
                LambdaQueryWrapper<CourseBase> queryWrapper = new LambdaQueryWrapper<>();
                // 课程名称
                if (!StringUtils.isEmpty(courseDto.getCourseName())) {
                        queryWrapper.like(CourseBase::getName, courseDto.getCourseName());
                }
                // 课程审核状态
                if (!StringUtils.isEmpty(courseDto.getAuditStatus())) {
                        queryWrapper.eq(CourseBase::getAuditStatus, courseDto.getAuditStatus());
                }
                // 课程类型
                if (!StringUtils.isEmpty(courseDto.getTeachmode())) {
                        queryWrapper.eq(CourseBase::getTeachmode, courseDto.getTeachmode());
                }
                //注释是因为 采用了mybatis的多租户插件 从线程对象获取 存储的对象信息 再通过租插件拼接 机构id进行查询

                // 设置机构 id, 从线程对象中获取匹配
                //queryWrapper.eq(CourseBase::getCompanyId, AuthInfoHolder.getCompanyId());
                // 分页查询
                IPage<CourseBase> iPage = this.page(page, queryWrapper);
                // 转化返回
                return PageResponseResult.okResult(iPage.getTotal(), iPage.getRecords());
        }

        @Override
        public ResponseResult upload(MultipartFile uploadFile) throws Exception {
                // 指定文件
                InputStream inputStream = uploadFile.getInputStream();
                // 指定文件上传的 路径 名称
                String filePath = "/images/" + new SimpleDateFormat("yyyy/MM/dd/").format(new Date())
                        + UUID.randomUUID() + uploadFile.getOriginalFilename();
                //构造PutArgs函数 发送请求
                PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                        .contentType("image/jpg")
                        .stream(inputStream, inputStream.available(), -1)
                        .bucket(minioProperties.getBucket())
                        .object(filePath)
                        .build();
                // 发送请求
                minioClient.putObject(putObjectArgs);
                //拼接访问地址
                String urlPath = minioProperties.getDomain() + "/" + minioProperties.getBucket() + filePath;
                return ResponseResult.okResult(urlPath);
        }
        @Transactional
        @Override
        public ResponseResult saveCourseBase(CourseBaseDto dto) {
                // 验证数据格式
                if (StringUtils.isEmpty(dto.getName()) || StringUtils.isEmpty(dto.getTags()) || StringUtils.isEmpty(dto.getMt())
                        || StringUtils.isEmpty(dto.getSt()) || StringUtils.isEmpty(dto.getGrade()) || StringUtils.isEmpty(dto.getDescription())
                        || StringUtils.isEmpty(dto.getUsers()) || StringUtils.isEmpty(dto.getTeachmode()) || StringUtils.isEmpty(dto.getPic())
                        || StringUtils.isEmpty(dto.getCharge()) || StringUtils.isEmpty(dto.getPrice())) {
                        // 数据不合法异常
                        throw new BusinessException(ErrorCode.DATAERROR);
                }
                // 请求dto对象转为对应实体类
                CourseBase courseBase = BeanHelper.copyProperties(dto, CourseBase.class);
                // 设置机构数据
                // 设置审核状态
                courseBase.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS);
                courseBase.setStatus(CommonConstants.USING_FLAG);
                courseBase.setCompanyName(AuthInfoHolder.getAuthInfo().getCompanyName());
                courseBase.setAuditDate(new Date());
                courseBase.setPlanNum(0);
                // 保存
                boolean course = this.save(courseBase);
                if (!course) {
                        throw new BusinessException(ErrorCode.ADDEERROR);
                }
                // 保存成功后初始化当前课程的  一级课程大纲
                Teachplan teachplan = new Teachplan();
                teachplan.setPname(courseBase.getName());
                teachplan.setParentid(0L);
                teachplan.setGrade(CourseConstants.FIRST_LEVEL);
                teachplan.setCourseId(courseBase.getId());
                teachplan.setStatus(CommonConstants.USING_FLAG);
                teachplan.setCreateDate(new Date());
                teachplanService.save(teachplan);
                // 设置返回值对象容器
                HashMap map = new HashMap();
                map.put("courseBaseId", courseBase.getId());
                return ResponseResult.okResult(map);
        }

        @Override
        public ResponseResult updateCourseBase(CourseBaseDto dto) {
                // 验证数据格式
                if (StringUtils.isEmpty(dto.getName()) || StringUtils.isEmpty(dto.getTags()) || StringUtils.isEmpty(dto.getMt())
                        || StringUtils.isEmpty(dto.getSt()) || StringUtils.isEmpty(dto.getGrade()) || StringUtils.isEmpty(dto.getDescription())
                        || StringUtils.isEmpty(dto.getUsers()) || StringUtils.isEmpty(dto.getTeachmode()) || StringUtils.isEmpty(dto.getPic())
                        || StringUtils.isEmpty(dto.getCharge()) || StringUtils.isEmpty(dto.getPrice())) {
                        // 数据不合法异常
                        throw new BusinessException(ErrorCode.DATAERROR);
                }
                // 根据id查询课程
                CourseBase courseBase = this.getById(dto.getId());
                if (courseBase == null) {
                        throw new BusinessException(ErrorCode.DATAERROR);
                }
                // 判断是否为可修改状态
                String status = courseBase.getAuditStatus();
                if (!CourseConstants.AUDIT_DISPAST_STATUS.equals(status) &&
                        !CourseConstants.AUDIT_UNPAST_STATUS.equals(status)) {
                        throw new BusinessException(ErrorCode.UPDATEEERROR);
                }
                // 修改
                CourseBase base = BeanHelper.copyProperties(dto, CourseBase.class);
                boolean update = this.updateById(base);
                if(!update){
                        throw new BusinessException(ErrorCode.ADDEERROR);
                }
                // 返回
                HashMap map = new HashMap();
                map.put("courseBaseId",dto.getId());
                // 返回值
                return ResponseResult.okResult(map);
        }

        @Override
        public ResponseResult deleteById(Long courseId) {
                // 根据id查询课程
                CourseBase courseBase = this.getById(courseId);
                if (courseBase == null) {
                        throw new BusinessException(ErrorCode.DATAERROR);
                }
                // 判断是否为可删除状态
                String status = courseBase.getAuditStatus();
                if (!CourseConstants.AUDIT_UNPAST_STATUS.equals(status) && !CourseConstants.AUDIT_DISPAST_STATUS.equals(status)
                && !CourseConstants.AUDIT_UNLINE_STATUS.equals(status)) {
                        throw new BusinessException(ErrorCode.DELETEERROR);
                }
                // 逻辑删除
                boolean remove = this.removeById(courseId);
                if(!remove){
                        throw new BusinessException(ErrorCode.DELETEERROR);
                }
                return ResponseResult.okResult(null);
        }

        @Override
        public ResponseResult commit(Long courseBaseId) {
                // 根据id查询课程
                CourseBase courseBase = this.getById(courseBaseId);
                if(courseBase == null){
                        throw new BusinessException(ErrorCode.NOTFOUND);
                }
                // 设置课程状态
                courseBase.setAuditStatus(CourseConstants.AUDIT_COMMIT_STATUS);
                // 更新课程
                boolean update = this.updateById(courseBase);
                if(!update){
                        throw new BusinessException(ErrorCode.ERROR);
                }
                return ResponseResult.okResult();
        }

        @Override
        public ResponseResult approve(CourseAuditDto courseAuditDto) {
                // 根据id查询课程
                CourseBase courseBase = this.getById(courseAuditDto.getCourseBaseId());
                if(courseBase == null){
                        throw new BusinessException(ErrorCode.NOTFOUND);
                }
                // 设置课程状态
                courseBase.setAuditStatus(courseAuditDto.getAuditStatus());
                courseBase.setAuditMind(courseAuditDto.getAuditMind());
                // 跟新审核状态
                boolean update = this.updateById(courseBase);
                if(!update){
                        throw new BusinessException(ErrorCode.ERROR);
                }
                return ResponseResult.okResult();
        }

        @Autowired
        private CoursePubServiceImpl coursePubService;

        @Override
        @Transactional
        public ResponseResult offline(Long courseId) {
                // 根据id查询课程
                CourseBase course = this.getById(courseId);
                if (course == null) {
                        throw new BusinessException(ErrorCode.DATAERROR);
                }
                // 判断是否为已发布状态
                if(!CourseConstants.AUDIT_PUBLISHED_STATUS.equals(course.getAuditStatus())){
                        throw new BusinessException(ErrorCode.MEDIABINDERROR);
                }
                // 课程下架-- 修改审核状态为 未提交
                course.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS);
                // 更新状态
                boolean update = this.updateById(course);
                if (!update){
                        throw new BusinessException(ErrorCode.UPDATEEERROR);
                }
                //删除所有相关信息{minio sql 发送mq消息}
                coursePubService.deleteById(courseId);
                return ResponseResult.okResult();
        }
}
